#include "AdapterManager.h"
#include "DeviceControl.h"

CDeviceControl::CDeviceControl()
{
	m_bPreReady = false;
	//m_timer.Create(1000, CDeviceControl::TimerThread, (unsigned long)this);
	//m_preTimer.Create(6 * 1000, CDeviceControl::PreTimerThread, (unsigned long)this);
}

CDeviceControl::~CDeviceControl()
{
	//m_timer.Destroy();
	//m_preTimer.Destroy();
}

int CDeviceControl::StartRecord(const char *pResid, int nDuration, char *pFileName)
{
	int nRet = J_OK;
	std::map<std::string, RecordInfo>::iterator it = m_recordMap.find(pResid);
	if (it == m_recordMap.end())
	{
		RecordInfo info;
		info.pRecord = new CStreamRecord();
		info.bPreRecord = false;
		info.nPreCount = 0;
		info.nCount = 1;

		m_recordMap[pResid] = info;
		nRet = m_recordMap[pResid].pRecord->StartRecord(pResid, nDuration, pFileName);
	}
	else
	{
		if (it->second.nCount == 0)
			nRet = it->second.pRecord->StartRecord(pResid, nDuration, pFileName);

		++it->second.nCount;
	}

	return nRet;
}

int CDeviceControl::StopRecord(const char *pResid)
{
	int nRet = J_OK;
	std::map<std::string, RecordInfo>::iterator it = m_recordMap.find(pResid);
	if (it == m_recordMap.end())
	{
		J_OS::LOGINFO("CDeviceControl::StopRecord not exist, resid = %s", pResid);
		return J_NOT_EXIST;
	}
	else
	{
		if (it->second.nCount == 1)
		{
			nRet = it->second.pRecord->StopRecord(pResid);
			if (!it->second.bPreRecord && it->second.nPreCount == 0)
				m_recordMap.erase(it);

			it->second.nCount = 0;
		}
		else
		{
			--it->second.nCount;
		}
	}

	return nRet;
}

int CDeviceControl::StartPreRecord(const char *pResid, int nTimeLen)
{
	int nRet = J_OK;
	std::map<std::string, RecordInfo>::iterator it = m_recordMap.find(pResid);
	if (it == m_recordMap.end())
	{
		RecordInfo info;
		info.pRecord = new CStreamRecord();
		info.bPreRecord = true;
		info.nPreCount = 1;
		info.nCount = 0;

		m_recordMap[pResid] = info;
		m_recordMap[pResid].pRecord->StartPreRecord(pResid, 0, nTimeLen);
	}
	else
	{
		++it->second.nPreCount;
	}

	return nRet;
}

int CDeviceControl::StopPreRecord(const char *pResid)
{
	int nRet = J_OK;
	std::map<std::string, RecordInfo>::iterator it = m_recordMap.find(pResid);
	if (it == m_recordMap.end())
	{
		J_OS::LOGINFO("CDeviceControl::StopPreRecord not exist, resid = %s", pResid);
		return J_NOT_EXIST;
	}
	else
	{
		if (it->second.nPreCount == 1)
		{
			nRet = m_recordMap[pResid].pRecord->StopPreRecord(pResid, 0);
			m_recordMap.erase(pResid);
			it->second.nPreCount = 0;
		}
		else
		{
			--it->second.nPreCount;
		}
	}

	return nRet;
}

int CDeviceControl::PtzControl(const char *pResid, int nCmd, int nParam)
{
	if (memcmp(pResid, "-1", 2) == 0)
		return J_NOT_EXIST;

	J_PtzControl *pPtzControl = dynamic_cast<J_PtzControl *>((J_ChannelStream *)CAdapterFactory::Instance()->GetInstance(pResid, OBJ_CHANNEL, 1));
	if (pPtzControl == NULL)
	{
		J_OS::LOGINFO("CDeviceControl::PtzControl GetInstence error");
		return J_NOT_EXIST;
	}

	return pPtzControl->PtzControl(nCmd, nParam);
}

/*int CDeviceControl::EnumFileList(const char *pResid, time_t beginTime, time_t endTime, sublist &fileList)
{
	J_VideoChannel *pVideoChannel = static_cast<J_VideoChannel *>(CAdapterFactory::Instance()->GetInstance(pResid, OBJ_CHANNEL));
	if (pVideoChannel == NULL)
	{
		J_OS::LOGINFO("CDeviceControl::PtzControl GetInstence error");
		return J_NOT_EXIST;
	}

	std::vector<FileInfo> vecFileInfo;
	if (pVideoChannel->EmunFileByTime(beginTime, endTime, vecFileInfo) == J_OK)
	{
		std::vector<FileInfo>::iterator it = vecFileInfo.begin();
		for (; it != vecFileInfo.end(); it++)
		{
			LIST_ITEM item;
			memset(&item, 0, sizeof(LIST_ITEM));
			memcpy(item.id, it->sFileName, strlen(it->sFileName));
			item.startTime = it->tStartTime;
			item.duration = (it->tStoptime - it->tStartTime);

			fileList.push_back(item);
		}
	}

	return J_OK;
}

int CDeviceControl::ProcessMsg(Message *pMsg, int nMsgType)
{
	if (nMsgType == CLIENT_PTZ_CNTL)
	{
		CNTL_INFO *ptzMessage = dynamic_cast<CNTL_INFO *>(pMsg);
		if (ptzMessage != NULL)
		{
			PtzControl(ptzMessage->m_resId, ptzMessage->m_ptzAction, atoi(ptzMessage->m_param));
		}
		//J_OS::LOGINFO("CDeviceControl::ProcessMsg PTZ_Control");

		strcpy(ptzMessage->m_strResult,"1"); //控制成功
		Dispatcher::Instance()->DispatchMsg(DEV_OPEN_MESSAGE, pMsg);
	}
	else if (nMsgType == VIDEO_MSG)
	{
		VIDEOMSG *videoMessage = dynamic_cast<VIDEOMSG *>(pMsg);
		if (videoMessage != NULL)
		{
			if (videoMessage->m_posId >= 0)
			{
				//转到预置点
				PtzControl(videoMessage->m_target, PTZ_GOTO_PRE, videoMessage->m_posId);
				Dispatcher::Instance()->DispatchMsg(VIDEO_MSG_REPLAY, pMsg);
			}
			else if (videoMessage->m_duration > 0)
			{
				std::map<std::string, DurationInfo>::iterator it = m_recordDurationMap.find(videoMessage->m_target);
				if (it == m_recordDurationMap.end())
				{
					//启动录像
					StartRecord(videoMessage->m_target, videoMessage->m_duration, videoMessage->m_filename);

					DurationInfo info;
					info.duration = videoMessage->m_duration;
					info.pMessage = videoMessage;
					m_recordDurationMap[videoMessage->m_target] = info;
					J_OS::LOGINFO("CDeviceControl::ProcessMsg Record_Control resid = %s", videoMessage->m_target);
				}
				else
				{
					it->second.curTimes = 0;
				}
			}
			else if (videoMessage->m_pre_duration > 0)
			{
				//启动预录
				StartPreRecord(videoMessage->m_target, videoMessage->m_pre_duration);
				Dispatcher::Instance()->DispatchMsg(VIDEO_MSG_REPLAY, pMsg);
			}
			else if (videoMessage->m_pre_duration < 0)
			{
				//停止预录
				StopPreRecord(videoMessage->m_target);
				Dispatcher::Instance()->DispatchMsg(VIDEO_MSG_REPLAY, pMsg);
			}
		}
		else
		{
			J_OS::LOGINFO("CDeviceControl::ProcessMsg param error");
		}
	}
	else if (nMsgType == CLIENT_QUERY_VIDEO)
	{
		VIDEO_QUERY *fileMessage = dynamic_cast<VIDEO_QUERY *>(pMsg);
		if (fileMessage != NULL)
		{
			EnumFileList(fileMessage->m_resid, fileMessage->m_starttime, fileMessage->m_endtime, fileMessage->m_slist);
		}
		J_OS::LOGINFO("CDeviceControl::ProcessMsg QueryFileList");

		Dispatcher::Instance()->DispatchMsg(VIDEO_QUERY_REPLAY, pMsg);
	}

	return J_OK;
}*/

void CDeviceControl::OnTimer()
{
	std::map<std::string, DurationInfo>::iterator it = m_recordDurationMap.begin();
	for (; it != m_recordDurationMap.end(); it++)
	{
		++it->second.curTimes;
	}

StopRecordLoop:
	it = m_recordDurationMap.begin();
	for (; it != m_recordDurationMap.end(); it++)
	{
		//J_OS::LOGINFO("%d >= %d", it->second.curTimes, it->second.duration);
		if (it->second.curTimes >= it->second.duration)
		{
			StopRecord(it->first.c_str());
			StopPreRecord(it->first.c_str());
			m_recordDurationMap.erase(it);
			//Dispatcher::Instance()->DispatchMsg(VIDEO_MSG_REPLAY, it->second.pMessage);

			goto StopRecordLoop;
		}
	}
}

void CDeviceControl::OnPreTimer()
{
	/*if (!CDBHelper::Instance()->IsReady() || m_bPreReady)
		return;

	RecordList preRecordList;
	CDBHelper::Instance()->GetDB().GetResidRecord(preRecordList);

	RecordIt it = preRecordList.begin();
	for (; it != preRecordList.end(); it++)
	{
		if (std::string(it->resid) != "")
		{
			if (m_preMap.find(it->resid) == m_preMap.end())
			{
				PreInfo preInfo;
				preInfo.duration = it->duration;
				m_preMap[it->resid] = preInfo;
			}
		}
		else
			J_OS::LOGINFO("CDeviceControl::StartAllPreRecord Invalid Resid");
	}

	PreMap::iterator it2 = m_preMap.begin();
	for (; it2 != m_preMap.end(); it2++)
	{
		if (!it2->second.flag)
		{
			if (StartPreRecord(it2->first.c_str(), it2->second.duration) == J_OK)
				it2->second.flag = true;
		}
	}

	m_bPreReady = true;*/
}
